home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / clang / ebksrc.zip / EB3.CPP < prev    next >
C/C++ Source or Header  |  1991-08-10  |  6KB  |  319 lines

  1. /*
  2.  
  3.     eb3.cpp
  4.     8-10-91
  5.     Electronic Book
  6.  
  7.  
  8.     Copyright 1991
  9.     John W. Small
  10.     All rights reserved
  11.  
  12.     Licensed users of FlexList may use and modify this
  13.     tool for use in their programs.
  14.  
  15.  
  16.     PSW / Power SoftWare
  17.     P.O. Box 10072
  18.     McLean, Virginia 22102 8072 USA
  19.  
  20.     Voice: (703) 759-3838
  21.     CIS: 73757,2233
  22.  
  23.  
  24.     Notes:  The Electronic Book was coded to demonstrate
  25.     the various uses of FlexList.
  26.  
  27.  
  28. */
  29.  
  30. #include <eb3.hpp>
  31.  
  32. HyperTopic::HyperTopic(ifstream& f)
  33. {
  34.     char buf[MAX_HYPER_LINE];
  35.  
  36.     inlinks = outlinks = (char *)0;
  37.     contextLength = 0;
  38.     for (long epos = fpos = f.tellg();
  39.         f.getline(buf,MAX_HYPER_LINE);
  40.         epos = f.tellg())
  41.         if (!inlinks)  {
  42.             inlinks = extractLinksDup(buf,1);
  43.             if (inlinks)
  44.                 fpos = f.tellg();
  45.         }
  46.         else  {
  47.             outlinks = extractLinksDup(buf,0);
  48.             if (outlinks)  {
  49.                 contextLength = epos - fpos;
  50.                 break;
  51.             }
  52.         }
  53.     if (inlinks && !outlinks)  {
  54.         delete inlinks;
  55.         inlinks = (char *)0;
  56.     }
  57. }
  58.  
  59. int HyperTopic::match(HyperTextTargeT HTT,
  60.     unsigned topicNum)
  61. {
  62.     if (!HTT) return 0;
  63.     if (HTT->Topic())  {
  64.         if (strcmpi(HTT->Topic(),parseLinks(inlinks)))
  65.             return 0;
  66.     }
  67.     else if (topicNum > 1)
  68.         return 0;
  69.     return 1;
  70. }
  71.  
  72. HyperContexT HyperTopic::fetch(HyperTextTargeT HTT,
  73.     unsigned topicNum)
  74. {
  75.     if (!match(HTT,topicNum) || !contextLength)
  76.         return HyperContexT0;
  77.     ifstream f(HTT->Fname(),ios::in|ios::binary);
  78.     if (!f)
  79.         return HyperContexT0;
  80.     if (!f.seekg(fpos))
  81.         return HyperContexT0;
  82.     char * c;
  83.     if ((c = new char [contextLength+1]) == (char *)0) {
  84.         f.close();
  85.         return HyperContexT0;
  86.     }
  87.     f.read(c,contextLength);
  88.     if (f.fail())  {
  89.         f.close();
  90.         delete c;
  91.         return HyperContexT0;
  92.     }
  93.     f.close();
  94.     c[contextLength] = '\0';
  95.     HyperContexT HC = new HyperContext(c,contextLength,
  96.         inlinks,outlinks,HTT->StartRow(),
  97.         HTT->StartColumn(),HTT->CursorRow(),
  98.         HTT->CursorColumn(),topicNum);
  99.     if (!HC)
  100.         delete c;
  101.     return HC;
  102. }
  103.  
  104. char * PickIndex::choice()
  105. {
  106.     char * C;
  107.     if ((C = (char *)PickListWindow::choice())
  108.         == (char *)0) return (char *)0;
  109.     for (int i = 0; C[i]; i++)
  110.         if (C[i] == HYPER_LINKS_DELIMIT)
  111.             if (C[++i])
  112.                 return &C[i];
  113.             else
  114.                 return (char *)0;
  115.     if (i)
  116.         return C;
  117.     return (char *)0;
  118. }
  119.  
  120. int   HyperFile::FNdestruct(void *ND, void *D)
  121. {
  122.     HyperTopiC HT = (HyperTopiC) ND;
  123.     if (D) return 0;
  124.     HT->HyperTopic::~HyperTopic();
  125.     return 1;
  126. }
  127.  
  128. HyperFile::HyperFile(const char *fname)
  129.     : FlexList(FLvariantData)
  130. {
  131.     void * getter;
  132.  
  133.     refs = 0;
  134.     this->fname[0] = '\0';
  135.     ifstream f(fname);
  136.     if (!f)
  137.         return;
  138.     HyperTopiC HT;
  139.     while (!f.eof())
  140.         if ((HT = new(insQD(&getter)) HyperTopic(f))
  141.             == HyperTopiC0)
  142.             break;
  143.         else if (!HT->ConstructOK()) {
  144.             mkcur(Nodes());
  145.             delD();
  146.             break;
  147.         }
  148.     if (f.bad())
  149.         clear();
  150.     else
  151.         strcpy(this->fname,fname);
  152.     f.close();
  153.     return;
  154. }
  155.  
  156. int HyperFile::match(HyperTextTargeT HTT)
  157. {
  158.     if (!HTT) return 0;
  159.     if (strcmpi(fname,HTT->Fname()))
  160.         return 0;
  161.     return 1;
  162. }
  163.  
  164. HyperContexT HyperFile::fetch(HyperTextTargeT HTT,
  165.     int backTrack)
  166. {
  167.     HyperTopiC HT;
  168.     HyperContexT HC;
  169.  
  170.     if (!match(HTT))
  171.         return HyperContexT0;
  172.     mkcur();
  173.     while ((HT = (HyperTopiC) nextD()) != HyperTopiC0)
  174.         if (HT->match(HTT,CurNum()))
  175.             if ((HC = HT->fetch(HTT,CurNum()))
  176.                 == HyperContexT0)
  177.                 return HyperContexT0;
  178.             else  {
  179.                 if (!backTrack)
  180.                     refs++;
  181.                 return HC;
  182.             }
  183.     return HyperContexT0;
  184. }
  185.  
  186. int HyperFile::discard(const char *fname)
  187. {
  188.  
  189.     if (strcmpi(fname,this->fname))
  190.         return -1;    // not this file
  191.     if (--refs > 0)
  192.         return 1;    // other links exist
  193.     return 0;        // ok to discard
  194. }
  195.  
  196. PickTOC HyperFile::TableOfContents(const char *fname)
  197. {
  198.     if (strcmpi(fname,this->fname))
  199.         return PickL0;    // not this file
  200.  
  201.     PickTOC TOC = new PickTableOfContents;
  202.  
  203.     if (TOC)  {
  204.         mkcur();
  205.         HyperTopiC HT;
  206.         while ((HT = (HyperTopiC) nextD())
  207.             != HyperTopiC0)
  208.             TOC->addT(HT->topic());
  209.  
  210.     }
  211.     return TOC;
  212. }
  213.  
  214. PickIDX HyperFile::Index(const char *fname)
  215. {
  216.     if (strcmpi(fname,this->fname))
  217.         return PickL0;    // not this file
  218.  
  219.     PickIDX IDX = new PickIndex;
  220.  
  221.     if (IDX)  {
  222.         mkcur();
  223.         HyperTopiC HT;
  224.         while ((HT = (HyperTopiC) nextD())
  225.             != HyperTopiC0)
  226.             if (IDX->addT(HT->topic()))
  227.                 while (IDX->addC(HT->clue()))
  228.                     /* null stmt */;
  229.     }
  230.     return IDX;
  231. }
  232.  
  233. int   HyperServer::FNdestruct(void *ND, void *D)
  234. {
  235.     HyperFilE HF = (HyperFilE) ND;
  236.     if (D) return 0;
  237.     HF->HyperFile::~HyperFile();
  238.     return 1;
  239. }
  240.  
  241.  
  242. HyperContexT HyperServer::fetch(HyperTextTargeT HTT,
  243.     int backTrack)
  244. {
  245.     HyperFilE HF;
  246.     HyperContexT HC;
  247.  
  248.     if (!HTT)
  249.         return HyperContexT0;
  250.  
  251.     // Look to see is file is already loaded.
  252.     mkcur();
  253.     while ((HF = (HyperFilE) nextD()) != HyperFilE0)
  254.         if (HF->match(HTT))
  255.             return HF->fetch(HTT,backTrack);
  256.  
  257.     // File isn't in memory, load it!
  258.  
  259.     void * getter;
  260.  
  261.     if ((HF = new (insQD(&getter))
  262.         HyperFile(HTT->Fname())) != HyperFilE0)
  263.         if (HF->ConstructOK())
  264.             return HF->fetch(HTT,0);
  265.         else  {
  266.             mkcur(Nodes());
  267.             delD();
  268.         }
  269.     return HyperContexT0;
  270. }
  271.  
  272.  
  273. void HyperServer::discard(const char *fname)
  274. {
  275.     if (!fname) return;
  276.  
  277.     mkcur();
  278.     HyperFilE HF;
  279.     while ((HF = (HyperFilE) nextD()) !=  HyperFilE0)
  280.         switch (HF->discard(fname))  {
  281.         case 1:
  282.             return;  // other links exist
  283.         case 0:
  284.             delD();
  285.             return;
  286.         case -1:
  287.         default:    // not this file
  288.             break;
  289.         }
  290. }
  291.  
  292. PickTOC HyperServer::TableOfContents(const char *fname)
  293. {
  294.     if (!fname) return PickL0;
  295.  
  296.     mkcur();
  297.     HyperFilE HF;
  298.     PickTOC TOC = PickTOC0;
  299.     while ((HF = (HyperFilE) nextD()) != HyperFilE0)
  300.         if ((TOC = HF->TableOfContents(fname))
  301.             != PickTOC0)
  302.             break;
  303.     return TOC;
  304. }
  305.  
  306. PickIDX HyperServer::Index(const char *fname)
  307. {
  308.     if (!fname) return PickIDX0;
  309.  
  310.     mkcur();
  311.     HyperFilE HF;
  312.     PickIDX IDX = PickIDX0;
  313.     while ((HF = (HyperFilE) nextD()) != HyperFilE0)
  314.         if ((IDX = HF->Index(fname))
  315.             != PickIDX0)
  316.             break;
  317.     return IDX;
  318. }
  319.